using System;
using Microsoft.Practices.RecipeFramework;
using EnvDTE;
using System.Runtime.Serialization;
using System.Xml; 

namespace Microsoft.Practices.RepositoryFactory.References
{
    /// <summary>
    /// A recipe reference that can point to an application configuration file, 
	/// either <c>App.config</c> or <c>Web.config</c>.
    /// </summary>
	[Serializable]
    public class ConfigurationFileRecipeReference : UnboundRecipeReference
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:ConfigurationFileRecipeReference"/> class.
        /// </summary>
        /// <param name="recipe">The recipe.</param>
        public ConfigurationFileRecipeReference(string recipe)
            : base(recipe)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:ConfigurationFileRecipeReference"/> class.
        /// </summary>
        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the reference.</param>
        /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
        protected ConfigurationFileRecipeReference(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        /// <summary>
        /// Checks if the target file contains a class.
        /// </summary>
        public override bool IsEnabledFor(object target)
        {
            ProjectItem item = target as ProjectItem;
            if (item == null || 
               !item.get_FileNames(1).EndsWith(".config", StringComparison.InvariantCultureIgnoreCase))
            {
                return false;
            }

			// Try to read as XML
			try
			{
				using (XmlReader reader = XmlReader.Create(item.get_FileNames(1)))
				{
					if (reader.MoveToContent() == XmlNodeType.Element &&
						reader.LocalName.Equals("configuration", StringComparison.InvariantCultureIgnoreCase))
					{
						return true;
					}
				}
				return false;
			}
			catch (XmlException)
			{
				return false;
			}
        }

        /// <summary>
        /// See <see cref="P:Microsoft.Practices.RecipeFramework.IAssetReference.AppliesTo"/>.
        /// </summary>
        /// <value></value>
        public override string AppliesTo
        {
            get { return Properties.Resources.ConfigurationFile_AppliesTo; }
        }
    }
}
